(function ($) {
	var me = {};
	window.Grid = Class.create({
		// 继承的父类
		Extends: Form,
		// 混入的集合
		//Mixes: EventMixin,
		// 静态方法
		//Statics: {},
		// 构造
		constructor: function(element, options){
			this.element = $(element);
			me = this;
			$.each(options,function(k,v){
				if( v == undefined && v == null ) return true;
				if( typeof v === 'object' ) {
					if( k == 'dataTablesOption' ) {
						me[k] = $.extend({}, me[k]);
						$.each(options[k],function(key,val){
							if( key == 'columns' ) {
								me[k][key] = $.extend([], val);
							} else {
								me[k][key] = typeof(me[k][key]) === 'object' ? $.extend({}, me[k][key], val) : val;
							}
						});
					} else {
						$.extend(me.get(k),v);
					}
				} else {
					me.set(k,v);
				}
			});
			// 设置配置
			if( me.searchFormId == '' )
				me.set('searchFormId',me.prefixId + "Search");
			// 设置配置
			if( me.uploadFormId == '' )
				me.set('uploadFormId',me.prefixId + "Upload");
		},
		// 主键字段
		pkField: "id",
		// 是否为树形结构
		isTreeGrid: 0,
		// 列表排序设置
		orderBy: "",
		// 上传表单ID
		uploadFormId: "",
		// 查询表单ID
		searchFormId: "",
		// 选中行索引
		selectIndexes: {},
		// 搜索表单元素配置
		searchOption: [],
		// 搜索表单元素模板
		searchElementTpl: '<label class="inline">' +
						'<span class="lbl">{0}：</span>' +
						'{1}' +
					'</label>',
		// 创建搜索表单元素
		createSearchElement: function(){
			var formId = me.searchFormId, $form = $("#" + formId);
			$form.attr('role','search')
			var searchOption = $form.data( "#" + formId );
			var ulParams = me.getUrlParams(), param = {};
			$.each(me.searchOption,function(k,v){
				if( ulParams[v.id] != undefined && ulParams[v.id] != '' ) {
					param[v.id] = ulParams[v.id];
				} else if( v.value != undefined && v.value != '' ) {
					param[v.id] = v.value;
				}
			});
			var formElementSettings = {
				prefixId: me.prefixId,
				apiPathPrefix: me.apiPathPrefix,
				elementOption: me.searchOption,
				elementTpl: me.searchElementTpl,
				editData: param
			};
			$('#' + me.searchFormId).formElement(formElementSettings);
		},
		// tab切换元素配置
		inboxTabsOption: {},
		// tab切换元素配置
		inboxTabsTpl: '<ul class="inbox-tabs nav nav-tabs padding-16 tab-size-bigger tab-space-1">' +
							'{0}' +
						'</ul>',
		// tab切换元素配置
		inboxTabsLiTpl: '<li class="{0}">' +
					'<a data-toggle="tab" href="#{2}" data-target="{4}">' +
						'<i class="blue ace-icon fa {3} bigger-130"></i>' +
						'<span class="bigger-110">{1}</span>' +
					'</a>' +
				'</li>',
		// tab切换数据处理
		inboxTabsRender: function () {
			if( $('.inbox-tabs li[class="active"]').html() == undefined ) {
				var tab = $('.inbox-tabs a[data-toggle="tab"]').eq(0);
				var hash = window.location.hash;
				var currentTab = tab.data('target');
				var href = tab.attr('href');
				if( href == undefined ) return;
				var hrefOption = me.paramString2obj(href.substr(1));
				var urlParams = $.extend({}, me.getUrlParams(), hrefOption);
				if( currentTab = 'inbox' ) {
					hash = ( hash.indexOf('?') == -1 ? hash : hash.substr(0,hash.indexOf('?')) ) + '?' + me.obj2paramString(urlParams);
					changeAjaxContent(hash);
				}
			}
			$('.inbox-tabs a[data-toggle="tab"]').on('show.bs.tab', function (e) {
				var hash = window.location.hash;
				var currentTab = $(e.target).data('target');
				var href = $(this).attr('href'), hrefOption = me.paramString2obj(href.substr(1));
				var urlParams = $.extend({}, me.getUrlParams(), hrefOption);
				if( currentTab = 'inbox' ) {
					hash = ( hash.indexOf('?') == -1 ? hash : hash.substr(0,hash.indexOf('?')) ) + '?' + me.obj2paramString(urlParams);
					changeAjaxContent(hash);
				}
			})
		},
		// tab切换按钮显示
		inboxTabsShow: function(){
			if( $.isEmptyObject(me.inboxTabsOption) ) return;
			var hash = window.location.hash;
			var html = '', i = 0, y = 0;
			$.each(me.inboxTabsOption,function(k,v){
				var href = v.href || '';
				if( hash.indexOf(href) != -1 ) {
					return false;
				}
				y++
			});
			$.each(me.inboxTabsOption,function(k,v){
				var href = v.href || '', icon = v.icon || '', target = v.target || 'inbox', active = '';
				if( i == y ) {
					active = 'active';
				}
				html += me.inboxTabsLiTpl.format(active,k,href,icon,target);
				i++
			});
			html = me.inboxTabsTpl.format(html);
			$("#" + me.prefixId + "InboxTabs").append(html);
			me.inboxTabsRender();
		},
		// 是否显示状态对应操作按
		isStatusOperating: true,
		// 状态字段名
		statusField: 'status',
		// 状态按钮div元素
		statusTpl: '<a class="{3}" title="{2}" id="{0}" href="javascript:;" onclick="{4}">' +
						'<i class="ace-icon fa {1}"></i>' +
					'</a>',
		// 状态数据处理
		statusRender: function ( data, type, row, meta ) {
			return me.showStatus(data, row);
		},
		// 状态对应操作
		statusOption: {
			"-1": "recycle",
			"0": "resume",
			"1": "forbid",
			"2": "checkPass",
		},
		// 显示安装按钮
		showStatus: function(type, row){
			var html = '', val = me[me.statusOption[type] + 'Button'];
			if( val == undefined ) return;
			var _id = val.id || "", _icon = val.icon || "", _title = val.title || "", _className = val.className || "";
			var action = me.statusOption[type] + 'Action';
			var _onclick = me.prefixId + "Table." + action + "('" + row[me.pkField] + "');";
			_id += '_' + row[me.pkField];
			html = val.buttonTpl != "" ? val.buttonTpl.format(_id,_icon,_title,_className,_onclick) : me.statusTpl.format(_id,_icon,_title,_className,_onclick);
			return html;
		},
		// 是否显示排序按钮
		isSortOperating: true,
		// 排序字段名
		sortField: 'sort',
		// 排序按钮div元素
		sortTpl: '<a href="javascript:;" title="{2}" class="{3}" onclick="{4}" >' +
					'<i class="ace-icon fa {1}"></i>' +
				'</a>',
		// 排序数据处理
		sortRender: function ( data, type, row, meta ) {
			return me.showSort(data, row);
		},
		// 显示排序按钮
		showSort: function(type, row){
			var html = '', val = me.sortButton;
			var _id = val.id || "", _icon = val.icon || "", _className = val.className || "";
			var sortArray = ['置顶','向上','置底','向下'];
			_id += '_' + row[me.pkField];
			var formParams = me.sortButton.params, formParamsArr = {};
			$.each(formParams,function(k,v){
				if( v == '' ) return true;
				if( v.toString().substr(0,1) == ':' ) {
					var param = row[v.toString().substr(1)];
					if( param !== undefined && param !== '' ) {
						formParamsArr[k] = param;
					}
				} else {
					formParamsArr[k] = v;
				}				
			});
			$.each(sortArray,function(k,v){
				var _onclick = me.prefixId + "Table.sortAction(" + (k+1) + ",'" + row[me.pkField] + "','" + encodeURIComponent(JSON.stringify(formParamsArr)) + "');";
				html += val.buttonTpl != "" ? val.buttonTpl.format(_id,_icon[k],v,_className,_onclick) : me.sortTpl.format(_id,_icon[k],v,_className,_onclick);
			});
			return html;
		},
		// 按钮列表
		buttons: ['add','edit','delete','remove','print','search','reset','export','import'],
		// 按钮背景div元素
		buttonBackdrop: '<div class="wizard-actions">' +
							'{0}' +
						'</div>',
		// 搜索按钮div元素
		buttonTpl: '<a class="{3}" title="{2}" id="{0}" href="javascript:;">' +
						'<i class="ace-icon fa {1}"></i>{2}' +
					'</a>',
		// 新增按钮
		addButton: {
			enable: false,
			id: "btnAdd",
			title: '新增',
			icon: "fa-plus",
			className: "btn btn-primary btn-sm",
			url: '/add_edit',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 新增操作
		addAction: function(){
			var url = me.addButton.url;
			url = ( url.indexOf(me.prefixId) == -1 ? me.prefixId : '') + url;
			var hash = url;
			hash += hash.indexOf('?') == -1 ? '?' : '';
			var hiddenParms = me.getHiddenParms();
			$.each(hiddenParms,function(k,v){
				hash += '&' + k + '=' + v;
			});
			changeAjaxContent(hash);
		},
		// 修改按钮
		editButton: {
			enable: false,
			id: "btnEdit",
			title: '修改',
			icon: "fa-pencil",
			className: "btn btn-primary btn-sm",
			url: '/add_edit',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 修改操作
		editAction: function(){
			var indexes = me.selectIndexes;
			var indexData = indexes[Object.keys(indexes)[Object.keys(indexes).length-1]];
			if( indexData == undefined ) {
				me.showMsg("请先选择行！");
				return;
			}
			var url = me.editButton.url;
			url = ( url.indexOf(me.prefixId) == -1 ? me.prefixId : '') + url;
			var hash = url + '?' + me.pkField + '=' + indexData[me.pkField];
			var hiddenParms = me.getHiddenParms();
			$.each(hiddenParms,function(k,v){
				hash += '&' + k + '=' + v;
			});
			var params = me.editButton.params;
			if( !$.isEmptyObject(params) ) {
				$.each(params,function(k,v){
					if( v == '' ) return true;
					if( v.toString().substr(0,1) == ':' ) {
						var param = indexData[v.toString().substr(1)];
						if( param !== undefined && param !== '' ) {
							hash += '&' + k + '=' + param;
						}
					} else {
						hash += '&' + k + '=' + v;
					}
				});				
			}
			changeAjaxContent(hash);
		},
		// 永久删除按钮
		deleteButton: {
			enable: false,
			id: "btnDelete",
			title: '删除',
			icon: "fa-trash-o",
			className: "btn btn-primary btn-sm",
			url: '/delete',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 永久删除操作
		deleteAction: function(){
			var rows = me.objGrid.rows({selected: true}), datas = rows.data(), params = [];
			for( var i = 0; i < datas.length; i++ ){
				params.push(datas[i][me.pkField]);
			}
			if( params.length == 0 ) {
				me.showMsg("请先选择行！");
				return;
			}
			var url = me.deleteButton.url;
			var dialogBtn = {
				success: {
					label: "确定",
					className: "btn-sm btn-primary",
					callback: function(){
						me.ajaxAction(url,params);
					}
				},
				cancel: "cancel"
			};
			me.showMsg('确定删除吗？',dialogBtn);
		},
		// 物理删除按钮
		removeButton: {
			enable: false,
			id: "btnRemove",
			title: '删除',
			icon: "fa-times",
			className: "btn btn-primary btn-sm",
			url: '/remove',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 物理删除操作
		removeAction: function(){
			var rows = me.objGrid.rows({selected: true}), datas = rows.data(), params = [];
			for( var i = 0; i < datas.length; i++ ){
				params.push(datas[i][me.pkField]);
			}
			if( params.length == 0 ) {
				me.showMsg("请先选择行！");
				return;
			}
			var url = me.removeButton.url;
			var dialogBtn = {
				success: {
					label: "确定",
					className: "btn-sm btn-primary",
					callback: function(){
						me.ajaxAction(url,params);
					}
				},
				cancel: "cancel"
			};
			me.showMsg('确定删除吗？',dialogBtn);
		},
		// 导出按钮
		exportButton: {
			enable: false,
			id: "btnExport",
			title: '导出',
			icon: "fa-cloud-download",
			className: "btn btn-primary btn-sm",
			url: '/export',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 导出操作
		exportAction: function(){
			var formId = me.searchFormId, $form = $("#" + formId), formData = $form.serializeArray();
			var url = me.getUrl(me.exportButton.url);
			// 获取附加参数
			var formParams = me.getFormParams(me.exportButton.params);
			$.each(formParams,function(k,v){
				if( v != null && v != undefined ) formData.push({name: k, value: v});
			});
			$.ajax({
				type: "post",
				dataType: "json",
				url: url,
				data: formData,
				async: false,
				success: function(data){
					if( data.isOk == 1 ) {
						me.jsonToExcel(data.result);
						me.objGrid.ajax.reload();
					} else {
						me.showMsg(data.message,dialogBtn);
					}
				},
				error: function(data){}
			});
		},
		// 导入按钮
		importButton: {
			enable: false,
			id: "btnImport",
			title: '导入',
			icon: "fa-cloud-upload",
			className: "btn btn-primary btn-sm",
			fieldName: "file",
			url: '/import',
			params: {},
			buttonTpl: '<div class="col-xs-3">' +
							'<form id="{4}" method="post" enctype ="multipart/form-data" role="file">' +
								'<input type="file" name="{5}" />' +
							'</form>' +
							'<a class="{3}" title="{2}" id="{0}" href="javascript:;">' +
								'<i class="ace-icon fa {1}"></i>{2}' +
							'</a>' +
						'</div>',
			afterAction: function(){
				var formId = me.uploadFormId, $form = $("#" + formId);
				$form.find('input[type=file]').ace_file_input({
					//style : 'well',
					no_file:'',
					btn_choose:'请选择',
					btn_change:'重新选择',
					droppable:false,
					onchange:null,
					thumbnail:false //| true | large
					//maxSize: 110000,//bytes
					//allowExt: ["jpeg", "jpg", "png", "gif"],
					//denyExt:[],
					//allowMime: ["image/jpg", "image/jpeg", "image/png", "image/gif"],
					//denyMime:[],
					//
				});
			},
		},
		// 导入操作
		importAction: function(){
			var formId = me.uploadFormId, $form = $("#" + formId), formData = {};
			var files = $form.find('input[type=file]')[0].files;
			if( !files ) return;
			var f = files[0];
			var reader = new FileReader();
			// 判断是否在新增修改页载入列表
			var hash = window.location.hash, hashArray = hash.split('/');
			var urlParams = me.getUrlParams();
			if( hash.indexOf('add_edit') != -1 ) {
				var pkField = window[hashArray[1]+'Form']['pkField'];
				if( urlParams[pkField] != undefined && urlParams[pkField] != '' ) {
					formData[pkField] = me.urlParams[pkField];
				}
			}
			// 获取附加参数
			var formParams = me.getFormParams(me.importButton.params);
			$.extend(formData,formParams);
			reader.onload = function(e) {
				var data = e.target.result;
				wb = XLSX.read(data, {
					type: 'binary'
				});
				//wb.SheetNames[0]是获取Sheets中第一个Sheet的名字
				//wb.Sheets[Sheet名]获取第一个Sheet的数据
				//document.getElementById("demo").innerHTML= JSON.stringify( XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]) );
				var jsonObj = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);//转化为JSON对象
				var jsonStr = JSON.stringify(jsonObj);//转化为JSON字符串
				formData[me.importButton.fieldName] = jsonStr;
				var url = me.getUrl(me.importButton.url);
				$.ajax({
					type: "post",
					dataType: "json",
					url: url,
					data: formData,
					async: false,
					success: function(data){
						var dialogBtn = {};
						if( data.isOk == 0 ) {
							dialogBtn = {
								success: {
									label: "导出错误",
									className: "btn-sm btn-primary",
									callback: function(){
										me.jsonToExcel(data.result);
									}
								},
								cancel: "cancel"
							};
						}
						me.showMsg(data.message,dialogBtn);
						me.objGrid.ajax.reload();
					},
					error: function(data){}
				});
			};
			reader.readAsBinaryString(f);
		},
		// 打印按钮
		printButton: {
			enable: false,
			id: "btnPrint",
			title: '打印',
			icon: "fa-print",
			className: "btn btn-primary btn-sm",
			url: '/print',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 打印操作
		printAction: function(){
		},
		// 查询按钮
		searchButton: {
			enable: false,
			id: "btnSearch",
			title: '查询',
			icon: "fa-search",
			className: "btn btn-primary btn-sm",
			url: '/search',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 查询操作
		searchAction: function(){
			var formId = me.searchFormId, $form = $("#" + formId);
			// 保存搜索条件
			$form.data( "#" + formId, JSON.stringify($form.serializeArray()) );
			me.objGrid.ajax.reload();
		},
		// 重置按钮
		resetButton: {
			enable: false,
			id: "btnReset",
			title: '重置',
			icon: "fa-undo",
			className: "btn btn-primary btn-sm",
			buttonTpl: "",
			afterAction: function(){},
		},
		// 重置操作
		resetAction: function(){
			var formId = me.searchFormId, $form = $("#" + formId);
			$form[0].reset();
			// 清楚缓存中的搜索条件
			$form.data("#" + formId, '');
			me.objGrid.ajax.reload();
		},
		// 还原按钮
		recycleButton: {
			id: "btnRecycle",
			title: '还原',
			icon: "fa-times",
			className: "btn btn-danger btn-sm",
			url: '/recycle',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 还原操作
		recycleAction: function(params){
			var url = me.recycleButton.url;
			me.ajaxAction(url,params);
		},
		// 恢复按钮
		resumeButton: {
			id: "btnResume",
			title: '恢复',
			icon: "fa-ban",
			className: "btn btn-default btn-sm",
			url: '/resume',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 恢复操作
		resumeAction: function(params){
			var url = me.resumeButton.url;
			me.ajaxAction(url,params);
		},
		// 禁用按钮
		forbidButton: {
			id: "btnForbid",
			title: '禁用',
			icon: "fa-check",
			className: "btn btn-success btn-sm",
			url: '/forbid',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 禁用操作
		forbidAction: function(params){
			var url = me.forbidButton.url;
			me.ajaxAction(url,params);
		},
		// 批准按钮
		checkPassButton: {
			id: "btnCheckPass",
			title: '批准',
			icon: "fa-pencil-square-o",
			className: "btn btn-primary btn-sm",
			url: '/checkPass',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 批准操作
		checkPassAction: function(params){
			var url = me.checkPassButton.url;
			me.ajaxAction(url,params);
		},
		// 排序按钮
		sortButton: {
			id: "btnSort",
			title: '排序',
			icon: [ 'fa-angle-double-up', 'fa-angle-up', 'fa-angle-double-down', 'fa-angle-down' ],
			className: "btn btn-primary btn-sm",
			url: '/sort',
			params: {},
			buttonTpl: "",
			afterAction: function(){},
		},
		// 排序操作
		sortAction: function(type, value, param){
			var param = JSON.parse(decodeURIComponent(param)) || {};
			var formId = me.searchFormId, $form = $("#" + formId);
			var url = me.sortButton.url, params = {};
			var hiddenParms = me.getHiddenParms();
			$.extend(hiddenParms,param);
			params[me.pkField] = value;
			params['type'] = type;
			params['params'] = JSON.stringify(hiddenParms);
			me.ajaxAction(url,params);
		},
		// 获取提交参数
		getFormParams: function( formParams ){
			var formData = {};
			if( !$.isEmptyObject(formParams) ) {
				var searchParams = me.getSearchParams();
				$.each(formParams,function(k,v){
					if( v == '' ) return true;
					if( v.toString().substr(0,1) == ':' ) {
						var param = searchParams[v.toString().substr(1)];
						if( param !== undefined && param !== '' ) {
							formData[k] = param;
						}
					} else {
						formData[k] = v;
					}
				});
			}			
			return formData;
		},
		// 获取搜索域参数
		getSearchParams: function(){
			var searchParams = {};
			$.each(me.searchOption,function(k,v){
				var value = $('.'+v.id).val();
				if( value !== '' ) searchParams[v.id] = value;
				if( v.op !== undefined && v.op == 'between' ) {
					var value1 = $('.'+v.id).eq(1).val();
					searchParams[v.id] = ( value !== '' ? value : '' ) + ',' + ( value1 !== '' ? value1 : '' );
					if( searchParams[v.id] == ',' ) delete searchParams[v.id];
				}
				if( v.type == 'treeview' ) {
					var items = $('.'+v.id).tree('selectedItems'), item = [];
					$.each(items,function(key,val){
						item.push(val[v.id]);
					});
					if( item.length != 0 ) searchParams[v.id] = item.join(',')
				}
			});
			return searchParams;
		},
		// 获取隐藏域参数
		getHiddenParms: function(){
			var formId = me.searchFormId, $form = $("#" + formId);
			var hiddenParms = {}, _hiddenParms = $form.find('input[type="hidden"]').serializeArray();
			$.each(_hiddenParms,function(k,v){
				if( me.pkField == v.name ) return true;
				hiddenParms[v.name] = v.value;
			});
			return hiddenParms;
		},
		// ajax公共方法
		ajaxAction: function(url, param){
			var url = me.getUrl(url), params = {};
			if( typeof(param) == 'string' ) {
				params[me.pkField] = param;
			} else if( Array.isArray(param) ) {
				params[me.pkField] = param.join(',');
			} else if( typeof(param) == 'object' ) {
				params = param;
			}
			$.ajax({
				type: "get",
				dataType: "json",
				url: url,
				data: params,
				success: function(data){
					me.showMsg(data.message);
					me.objGrid.ajax.reload();
				},
				error: function(data){}
			});
		},
		// 创建搜索按钮
		createSearchButtons: function(){
			var html = '', $form = $("#" + me.searchFormId);
			var btnDiv = $form.next('.wizard-actions').length;
			var buttons = ['search','reset','export'];
			$.each(me.buttons,function(k,v){
				var val = me[v + 'Button'];
				// 未启用则退出本次循环
				if( !val['enable'] ) return true;
				// 参数preview为1时，无提交按钮
				if( $.inArray(v,buttons) == -1 && ( me.urlParams.preview && me.urlParams.preview == 1 || me.urlParams.review && me.urlParams.review == 1 ) ) return true;
				var _id = val.id || "", _icon = val.icon || "", _title = val.title || "", _className = val.className || "";
				if( v == 'import' ) {
					html += val.buttonTpl.format(_id,_icon,_title,_className,me.uploadFormId,val.fieldName);
					html += '&nbsp; ';
				} else {
					html += val.buttonTpl != "" ? val.buttonTpl.format(_id,_icon,_title,_className) : me.buttonTpl.format(_id,_icon,_title,_className);
					html += '&nbsp; ';
				}
			});
			if( btnDiv > 0 ) {
				$form.next('.wizard-actions').append(html);
			} else {
				html = me.buttonBackdrop.format(html);
				$form.after(html);
			}
			// 绑定操作事件
			$.each(me.buttons,function(k,v){
				var val = me[v + 'Button'];
				// 未启用则退出本次循环
				if( !val['enable'] ) return true;
				// 参数preview为1时，无提交按钮
				if( $.inArray(v,buttons) == -1 && ( me.urlParams.preview && me.urlParams.preview == 1 || me.urlParams.review && me.urlParams.review == 1 ) ) return true;
				val.afterAction();
				var _event = me[v + 'Action'] || function(){};
				$("#" + val.id).on('click', function(){
					_event();
				});
			});
		},
		// 多选格式
		selectMultiCheckbox: {
			// 设置列的数据源，即如何从整个Table的数据源(object / array)中获得
			data: "id",
			// 设置列的标题
			title: '<label class="pos-rel">' +
						'<input type="checkbox" value="" class="ace" />' +
						'<span class="lbl"></span>' +
					'</label>',
			// 给列中每个单元格指定一个或多个class
			className: "center",
			// 开启/禁用这列是否排序
			orderable: false,
			// 按第一列和第二列排序作为默认排序
			orderData: [ 0, 1 ],
			// 按第一次降序，第二次升序，第三次升序，依次循环
			orderSequence: [ "desc", "asc", "asc" ],
			// 数据处理
			render: function ( data, type, row, meta ) {
				return '<label class="pos-rel">' +
							'<input type="checkbox" value="' + data + '" class="ace" />' +
							'<span class="lbl"></span>' +
						'</label>';
			}
		},
		// 树形格式
		treeGridControl: {
			data: "id",
			title: '',
			className: "treegrid-control",
			render: function ( data, type, row, meta ) {
				if (row.children) {
					return '<i class="ace-icon fa glyphicon-plus"></i>';
				}
				return '';
			}
		},
		// dataTables配置
		dataTablesOption: {
			/* 定义组件元素的显示
				`l` 代表 length，左上角的改变每页显示条数控件
				`f` 代表 filtering，右上角的过滤搜索框控件
				`t` 代表 table，表格本身
				`i` 代表 info，左下角的表格信息显示控件
				`p` 代表 pagination，右下角的分页控件
				`r` 代表 processing，表格中间的数据加载等待提示框控件
				`B` 代表 button，Datatables可以提供的按钮控件，默认显示在左上角
			 */
			dom: 'ftip',
			// 是否允许Datatables开启本地搜索
			searching: false,
			// 是否允许排序
			ordering: false,
			// 设置默认排序
			order: [[ 1, 'desc' ]],
			// 是否开启服务器模式
			serverSide: true,
			// 是否开启分页
			paging: true,
			// 每页显示多少条数据
			pageLength: 10,
			// tree配置
			'treeGrid': {
				'left': 10,
				'expandIcon': '<i class="ace-icon fa glyphicon-plus"></i>',
				'collapseIcon': '<i class="ace-icon fa glyphicon-minus"></i>'
			},
			// 语言配置选项
			language: {
				// 从远程获取语言信息
				url: "",
			},
			// 数据获取
			ajax: {
				// 请求地址
				url: '',
				// 数据属性或操作表数据的方法
				dataSrc: "result",
				data : function(data) {
					if( me.dataTablesOption.serverSide ) {
						for (var i = 0; i < data.columns.length; i++) {
							column = data.columns[i];
							column.searchRegex = column.search.regex;
							column.searchValue = column.search.value;
							delete (column.search);
						}
					}
					if( !me.dataTablesOption.ordering ) delete data.columns;
					if( !me.dataTablesOption.searching ) delete data.search;
				}
			},
			serverParams: function (aoData) {
				var searchParams = me.getSearchParams();
				$.extend(aoData,searchParams);
				if( me.isTreeGrid == 1 ) {
					aoData['isTree'] = 1;
				}
				if( me.orderBy != '' ) {
					aoData['orderBy'] = me.humpToInterval(me.orderBy);
				}
				//aoData._rand = Math.random();
			},
			// 设置定义列的初始属性
			columns: [
				{
					// 为一个或多个列编制定义，0为第一列，-1为最好一列
					targets: 0,
					// 设置列的数据源，即如何从整个Table的数据源(object / array)中获得
					data: "id",
					// 设置列的标题
					title: '<label class="pos-rel">' +
								'<input type="checkbox" value="" class="ace" />' +
								'<span class="lbl"></span>' +
							'</label>',
					// 给列中每个单元格指定一个或多个class
					className: "center",
					// 开启/禁用这列是否排序
					orderable: false,
					// 按第一列和第二列排序作为默认排序
					orderData: [ 0, 1 ],
					// 按第一次降序，第二次升序，第三次升序，依次循环
					orderSequence: [ "desc", "asc", "asc" ],
					// 数据处理
					render: function ( data, type, row, meta ) {
						return '<label class="pos-rel">' +
									'<input type="checkbox" value="' + data + '" class="ace" />' +
									'<span class="lbl"></span>' +
								'</label>';
					}
				},{
					targets: -1,
					data: "id",
					title: "",
					orderable: false,
					render: function ( data, type, row, meta ) {
						return '<div class="btn-group dropup">' +
									'<button data-toggle="dropdown" class="btn btn-primary btn-white dropdown-toggle">' +
										'操作' +
										'<i class="ace-icon fa fa-angle-down icon-on-right"></i>' +
									'</button>' +
									'<ul class="dropdown-menu dropdown-info dropdown-menu-right">' +
										'<li>' +
											'<a class="blue" data-url="page/form-elements" href="#page/form-elements" >' +
												'<i class="ace-icon fa fa-search-plus bigger-130"></i>' +
												'查看明细' +
											'</a>' +
										'</li>' +
									'</ul>' +
								'</div>';
					}
				}
			],
			select: {
				// 选择方式，单行：single，多行：multi
				style: 'single',
				// 允许选择除最后一列以外的所有列
				//selector: 'td:first-child',
			},
		},
		// dataTablesOption默认值
		_dataTablesOption: {
			language: {
				// 从远程获取语言信息
				url: "/resources/assets/data/grid-cn.json",
			},
		},
		// 显示列表
		showGrid: function(options){
			// 开启状态按钮显示时，自动填充
			if( me.isStatusOperating ) {
				$.each(options.columns,function(k,v){
					if( v.data != me.statusField && v.render != 'undefined' ) return true;
					options.columns[k]['render'] = me.statusRender;
				});
			}
			// 开启排序按钮显示时，自动填充
			if( me.isSortOperating ) {
				$.each(options.columns,function(k,v){
					if( v.data != me.sortField && v.render != 'undefined' ) return true;
					options.columns[k]['render'] = me.sortRender;
				});
			}
			// 多选情况下，增加第一列多选框
			if( me.dataTablesOption.select.style == 'multi' && ( options.columns[0].render == undefined || options.columns[0].render.indexOf('checkbox') == -1 ) ) {
				var selectMultiCheckbox = me.selectMultiCheckbox;
				selectMultiCheckbox.data = me.pkField;
				options.columns.unshift(selectMultiCheckbox);
			}
			// 树形结构情况下，增加一列下拉按钮
			if( me.isTreeGrid == 1 ) {
				var treeGridControl = me.treeGridControl;
				treeGridControl.data = me.pkField;
				options.columns.unshift(treeGridControl);
			}
			// 查询地址补全
			options.language.url = ( options.language.url.indexOf("//") == -1 ? app.contextPath : '') + me._dataTablesOption.language.url;
			options.ajax.url = me.getUrl(me.searchButton.url);
			// 渲染列表
			me.objGrid = me.element.DataTable(options);
			// 防止点击冲突
			me.objGrid.on('click', function(e) {
				e.stopImmediatePropagation();
				e.stopPropagation();
				e.preventDefault();
			});
			me.objGrid.on('draw', function(){
				$('.dropdown-toggle', this).dropdown();
			});
			// 选择
			me.objGrid.on( 'select', function ( e, dt, type, index ) {
				if ( type === 'row' ) {
					me.onClickRow('select', me.objGrid.row(index).index(), me.objGrid.row(index).data());
				}
			});
			// 取消选择
			me.objGrid.on( 'deselect', function ( e, dt, type, index ) {
				if ( type === 'row' ) {
					me.onClickRow('deselect', me.objGrid.row(index).index(), me.objGrid.row(index).data());
				}
			});
			// 点击复选框
			me.onClickbox();
		},
		// 点击行之前操作
		onClickRowBefor: function(type, rowIndex, rowData){},
		// 点击行之后操作
		onClickRowAfter: function(type, rowIndex, rowData){},
		// 点击行
		onClickRow: function(type, rowIndex, rowData){
			me.onClickRowBefor(type, rowIndex, rowData);
			var checked = false, indexes = me.selectIndexes;
			if( type == 'select' ) {
				checked = true;
				indexes['key'+rowIndex] = rowData;
			} else if( type == 'deselect' ) {
				checked = false;
				delete indexes['key'+rowIndex];
			}
			// 选中/取消行 - 则选中/取消复选框
			$(  me.objGrid.row(rowIndex).node() ).find('input:checkbox').prop('checked', checked);
			me.onClickRowAfter(type, rowIndex, rowData);
		},
		// 点击行复选框之前操作
		onClickboxBefor: function(rowIndex, rowData){},
		// 点击行复选框之后操作
		onClickboxAfter: function(rowIndex, rowData){},
		// 点击行复选框
		onClickbox: function(){
			var table = me.objGrid;
			// 选中头部checkbox则选中所有行
			me.element.on('click', 'th input[type=checkbox]' , function(){
				if( me.dataTablesOption.select.style == 'single' ) return true;
				var th_checked = this.checked;
				if( th_checked ) {
					me.element.find('td input[type=checkbox]').prop('checked', true);
					table.rows().select();
				} else {
					me.element.find('td input[type=checkbox]').prop('checked', false);
					table.rows().deselect();
				}
			});
			// 选中checkbox则选中整行
			me.element.on('click', 'td input[type=checkbox]' , function(){
				var _row = $(this).closest('tr'), row = _row.get(0), index = _row.index();
				me.onClickboxBefor(index, table.row(row).data());
				// 单选情况下其他行取消选中
				if( me.dataTablesOption.select.style == 'single' ) {
					me.element.find('th input[type=checkbox]').prop('checked', false);
					me.element.find('td input[type=checkbox]:checked').each(function(){
						if( $(this).closest('tr').index() != index ) $(this).prop('checked', false);
					});
					table.rows().deselect();
				}
				// 选中该行
				if( this.checked ) {
					table.row(row).select();
				} else {
					table.row(row).deselect();
				}
				me.onClickboxAfter(index, table.row(row).data());
			});
		},
		// 创建Element
		load: function(option){
			var hash = window.location.hash, hashArray = hash.split('/');
			if( hash.indexOf('add_edit') != -1 ) {
				var urlParams = me.getUrlParams();
				var pkField = window[hashArray[1]+'Form']['pkField'];
				if( urlParams[pkField] == undefined || urlParams[pkField] == '' ) {
					$('.widget-box').addClass('hidden');
					return;
				}
			}
			me.beforeLoad();
			me.inboxTabsShow();
			me.createSearchElement();
			me.createSearchButtons();
			me.showGrid(option);
			me.afterLoad();
		},
		// 加载数据前操作
		beforeLoad: function(){},
		// 加载数据之后操作
		afterLoad: function(){},
	});
    /**
     * 扩展 Jquery 对象为 Grid
     * @param option
     */
	$.fn.grid = function(option){
		return this.each(function () {
			var $this = $(this),
				data = $this.data('grid'),
				options = typeof option === 'object' && option;
			if (!data)  {
				$this.data('grid', (data = new Grid(this, $.extend({}, options))));
			}
			if (typeof option == 'string') {
				data[option]();
			}
			if(data.autoLoad){
				data.load(data.dataTablesOption);
			}
		});
	};
	// 属性返回对创建此对象的函数的引用
	$.fn.grid.Constructor = Grid;

})(jQuery);
